/* State.h
Michael Zahniser, 12/12/09

Header file for the calculator State class.
*/

#ifndef __MZ_STATE_H__
#define __MZ_STATE_H__

#include <string>
#include <vector>
#include <map>



class State {
public:
	State();
	// Trust the built-in copy and assignment.
	
	// Clear the stack.
	void Clear();
	// Reset the state entirely (clear all variables and functions).
	void Reset();
	
	// Determine the current operating mode.
	enum EntryMode {
		CALCULATING,
		PROGRAMMING,
		DEFINING,
		SKIPPING
	};
	EntryMode Mode() const;
	void SetMode(EntryMode mode);
	
	// Determine the current base.
	int Base() const;
	void SetBase(int base);
	// Toggle between degrees and radians.
	enum AngleMode {
		DEGREES,
		RADIANS
	};
	AngleMode Angle() const;
	void SetAngle(AngleMode angle);
	
	const std::vector<double> Stack() const;
	const std::vector<std::string> Function() const;
	
	// Access the stack of values.
	double Pop();
	long long PopInt();
	void Push(double value);
	// Add a word, uninterpreted.
	// If functionming, it gets added onto the function.
	// If defining, the word is used as the variable or function name.
	void Push(const std::string &word);
	
	// Check if the given word is a variable.
	bool HasVariable(const std::string &word);
	double Variable(const std::string &word);
	// Check if the given word is a function.
	bool HasFunction(const std::string &word);
	const std::vector<std::string> &Function(const std::string &word);
	
	
private:
	std::vector<double> stack;
	std::vector<std::string> function;
	
	std::map<std::string, double> variables;
	std::map<std::string, std::vector<std::string> > functions;
	
	EntryMode mode;
	int base;
	AngleMode angle;
};

#endif
